package com.multi.tool.java8function;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

@Slf4j
@Component
public class Locks {
    @Autowired
//    RedisTemplate<String, String> redisTemplate;

    public <R> R supplier(String key, Supplier<R> fun) {
        log.info("获取分布式锁: {}", key);
        try {
//            if (!redisTemplate.opsForValue().setIfAbsent(key, "1")) {
//                throw new ServiceException(RestStatus.THREE_ERROR);
//            }
            return fun.get();
        } finally {
//            redisTemplate.delete(key);
        }
    }

    @Transactional
    public <R> R supplierInTransaction(Supplier<R> fun) {
        return fun.get();
    }

    public <T, R> R function(String key, T t, Function<T, R> fun) {
        log.info("获取分布式锁: {}", key);
        try {
//            if (!redisTemplate.opsForValue().setIfAbsent(key, "1")) {
//                throw new ServiceException(RestStatus.THREE_ERROR);
//            }
            return fun.apply(t);
        } finally {
//            redisTemplate.delete(key);
        }
    }

    @Transactional
    public <T, R> R functionInTransaction(T t, Function<T, R> fun) {
        return fun.apply(t);
    }

    public <T, R> void consumer(String key, T t, Consumer<T> fun) {
        log.info("获取分布式锁: {}", key);
        try {
//            if (!redisTemplate.opsForValue().setIfAbsent(key, "1")) {
//                throw new ServiceException(RestStatus.THREE_ERROR);
//            }
            fun.accept(t);
        } finally {
//            redisTemplate.delete(key);
        }
    }

    @Transactional
    public <T, R> void consumerInTransaction(T t, Consumer<T> fun) {
        fun.accept(t);
    }

    public <T, R> Boolean predicate(String key, T t, Predicate<T> fun) {
        log.info("获取分布式锁: {}", key);
        try {
//            if (!redisTemplate.opsForValue().setIfAbsent(key, "1")) {
//                throw new ServiceException(RestStatus.THREE_ERROR);
//            }
            return fun.test(t);
        } finally {
//            redisTemplate.delete(key);
        }
    }

    @Transactional
    public <T, R> Boolean predicateInTransaction(T t, Predicate<T> fun) {
        return fun.test(t);
    }

    @Transactional
    public void action(String key, Runnable runnable) {
        log.info("获取分布式锁: {}", key);
        try {
//            if (!redisTemplate.opsForValue().setIfAbsent(key, "1")) {
//                throw new ServiceException(RestStatus.THREE_ERROR);
//            }
            runnable.run();
        } finally {
//            redisTemplate.delete(key);
        }
    }
}
